/**
 * 网络请求工具类 - WeUI版本
 * 封装了axios，使用WeUI组件进行交互反馈
 */
class Request {
  constructor(options = {}) {
    // 检查依赖
    if (typeof axios === 'undefined') {
      throw new Error('axios未加载，请确保在request.js之前引入axios');
    }
    if (typeof weui === 'undefined') {
      throw new Error('weui未加载，请确保在request.js之前引入weui');
    }

    // 创建axios实例
    this.instance = axios.create({
      baseURL: options.baseURL || '',
      timeout: options.timeout || 15000,
      headers: options.headers || {
        'Content-Type': 'application/json;charset=UTF-8'
      }
    });

    // 是否显示loading
    this.showLoading = options.showLoading !== false;
    this.loadingInstance = null; // 保存loading实例

    // 请求重试配置
    this.retryConfig = {
      retry: options.retry || 3, // 重试次数
      retryDelay: options.retryDelay || 1000, // 重试间隔
      shouldRetry: options.shouldRetry || ((error) => {
        // 默认只在网络错误或超时时重试
        return !error.response || error.code === 'ECONNABORTED';
      })
    };

    // 初始化拦截器
    this.initInterceptors();
  }

  /**
   * 初始化拦截器
   */
  initInterceptors() {
    // 请求拦截器
    this.instance.interceptors.request.use(
      (config) => {
        // 在发送请求之前做些什么
        if (this.showLoading) {
          this.showLoadingIndicator();
        }

        // 添加公共参数（如token等）
        const token = localStorage.getItem('token') || '';
        if (token) {
          config.headers['Authorization'] = `Bearer ${token}`;
        }

        // 微信相关配置
        if (window.wx && config.url.includes('/wechat/')) {
          config.headers['X-WX-CODE'] = wx.getStorageSync('wx_code');
          config.headers['X-WX-OPENID'] = wx.getStorageSync('wx_openid');
        }

        return config;
      },
      (error) => {
        // 对请求错误做些什么
        this.hideLoadingIndicator();
        return Promise.reject(error);
      }
    );

    // 响应拦截器
    this.instance.interceptors.response.use(
      (response) => {
        this.hideLoadingIndicator();
        
        // 对响应数据做点什么
        const res = response.data;
        
        // 自定义状态码处理
        if (res.code !== undefined && res.code !== 200) {
          // 处理业务错误
          this.handleBusinessError(res);
          return Promise.reject(res);
        }
        
        return res;
      },
      (error) => {
        this.hideLoadingIndicator();
        
        // 对响应错误做点什么
        if (error.response) {
          // 处理HTTP错误状态码
          this.handleHttpError(error);
        } else {
          // 处理网络错误
          this.handleNetworkError(error);
        }
        
        return Promise.reject(error);
      }
    );
  }

  /**
   * 显示WeUI加载指示器
   */
  showLoadingIndicator() {
    // 先隐藏已有的loading
    this.hideLoadingIndicator();
    
    // 使用WeUI的loading效果并保存实例
    this.loadingInstance = weui.loading('加载中...', {
      className: 'custom-loading'
    });
  }

  /**
   * 隐藏WeUI加载指示器
   */
  hideLoadingIndicator() {
    if (this.loadingInstance) {
      // WeUI 2.x版本使用hide()方法
      if (typeof this.loadingInstance.hide === 'function') {
        this.loadingInstance.hide();
      }
      this.loadingInstance = null;
    }
  }

  /**
   * 处理业务错误
   * @param {Object} error 错误对象
   */
  handleBusinessError(error) {
    const errorMap = {
      401: '未授权，请重新登录',
      403: '拒绝访问',
      404: '请求资源不存在',
      500: '服务器错误',
      503: '服务不可用'
    };
    
    const message = error.msg || error.message || errorMap[error.code] || '未知错误';
    
    this.showToast(message, 'error');
    
    // 未授权跳转登录页
    if (error.code === 401) {
      setTimeout(() => {
        window.location.href = '/login?redirect=' + encodeURIComponent(window.location.href);
      }, 1500);
    }
  }

  /**
   * 处理HTTP错误
   * @param {Object} error 错误对象
   */
  handleHttpError(error) {
    const status = error.response.status;
    let message = '';
    
    switch (status) {
      case 400:
        message = '请求参数错误';
        break;
      case 401:
        message = '未授权，请重新登录';
        setTimeout(() => {
          window.location.href = '/login?redirect=' + encodeURIComponent(window.location.href);
        }, 1500);
        break;
      case 403:
        message = '拒绝访问';
        break;
      case 404:
        message = '请求资源不存在';
        break;
      case 500:
        message = '服务器错误';
        break;
      case 503:
        message = '服务不可用';
        break;
      default:
        message = `连接错误 ${status}`;
    }
    
    this.showToast(message, 'warn');
  }

  /**
   * 处理网络错误
   * @param {Object} error 错误对象
   */
  handleNetworkError(error) {
    if (error.message.includes('timeout')) {
      this.showToast('请求超时，请检查网络连接', 'warn');
    } else if (error.message.includes('Network Error')) {
      this.showToast('网络错误，请检查网络连接', 'warn');
    } else {
      this.showToast('未知错误，请联系管理员', 'warn');
    }
  }

  /**
   * 显示WeUI Toast提示
   * @param {String} message 消息内容
   * @param {String} type 类型 (success/warn)
   * @param {Number} duration 显示时间(ms)
   */
  showToast(message, type = 'success', duration = 2000) {
    weui.toast(message, {
      className: `weui-toast_${type}`,
      duration: duration
    });
  }

  /**
   * 显示确认对话框
   * @param {String} message 消息内容
   * @param {Function} confirmCallback 确认回调
   * @param {Function} cancelCallback 取消回调
   */
  showConfirm(message, confirmCallback, cancelCallback) {
    weui.confirm(message, {
      title: '提示',
      buttons: [{
        label: '取消',
        type: 'default',
        onClick: cancelCallback
      }, {
        label: '确定',
        type: 'primary',
        onClick: confirmCallback
      }]
    });
  }

  /**
   * 发起GET请求
   * @param {String} url 请求地址
   * @param {Object} params 请求参数
   * @param {Object} config 请求配置
   * @returns {Promise}
   */
  get(url, params = {}, config = {}) {
    return this.instance.get(url, {
      params,
      ...config
    });
  }

  /**
   * 发起POST请求
   * @param {String} url 请求地址
   * @param {Object} data 请求数据
   * @param {Object} config 请求配置
   * @returns {Promise}
   */
  post(url, data = {}, config = {}) {
    return this.instance.post(url, data, config);
  }

  /**
   * 发起PUT请求
   * @param {String} url 请求地址
   * @param {Object} data 请求数据
   * @param {Object} config 请求配置
   * @returns {Promise}
   */
  put(url, data = {}, config = {}) {
    return this.instance.put(url, data, config);
  }

  /**
   * 发起DELETE请求
   * @param {String} url 请求地址
   * @param {Object} config 请求配置
   * @returns {Promise}
   */
  delete(url, config = {}) {
    return this.instance.delete(url, config);
  }

  /**
   * 发起请求（通用方法）
   * @param {Object} config 请求配置
   * @returns {Promise}
   */
  request(config) {
    return this.instance.request(config);
  }

  /**
   * 设置请求重试
   * @param {Function} requestFn 请求函数
   * @param {Object} config 重试配置
   * @returns {Promise}
   */
  withRetry(requestFn, config = {}) {
    const retryConfig = {
      ...this.retryConfig,
      ...config
    };
    
    let retryCount = 0;
    
    const execute = async () => {
      try {
        return await requestFn();
      } catch (error) {
        if (retryCount < retryConfig.retry && retryConfig.shouldRetry(error)) {
          retryCount++;
          await new Promise(resolve => setTimeout(resolve, retryConfig.retryDelay));
          return execute();
        }
        throw error;
      }
    };
    
    return execute();
  }
}

// 创建默认实例并暴露到全局
const request = new Request({
  baseURL: 'https://www.gdwl.cc/api',
  timeout: 15000,
  showLoading: true
});

window.request = request;